package com.superman.mvpframe.client.widget.pop;

import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
import com.superman.mvpframe.client.gin.XGinjector;
import com.superman.mvpframe.client.history.PopStateEvent;
import com.superman.mvpframe.client.history.PopStateHandler;

/**
 * 渐入渐出的弹框
 * 
 * @author superman
 * @version 2018年7月24日下午11:45:45
 */
public class FadePopupWindow extends Composite {

	private HandlerRegistration animationEnd; // 记录container的animationHandler
	// 加入多个元素时的容器
	private Widget container;

	private boolean hideOnBgClick; // 是否通过点击遮罩隐藏
	private boolean isShow; // 是否在展示

	private double opacity = 0.4;
	// 灰色遮罩层
	private FlowPanel panelToPopup;
	private AnimationEndHandler showAnimationHandler, hideAnimationHandler;

	/**
	 * 构造方法
	 * 
	 * @author superman
	 * @version 2018年7月24日 下午11:46:30
	 */
	public FadePopupWindow() {
		super();

		panelToPopup = new FlowPanel();
		XGinjector.INSTANCE.getHtml5Historian().addPopStateHandler(new PopStateHandler() {

			@Override
			public void onPopStateEvent(PopStateEvent event) {
				hide();
			}
		});
	}

	/**
	 * 添加元素
	 * 
	 * @author superman
	 * @version 2018年7月24日 下午11:46:59
	 * @param widget
	 */
	public void add(Widget widget) {
		container = widget;
		panelToPopup.add(widget);
	}

	private void addAnimationHandler(AnimationEndHandler handler) {
		if (animationEnd != null)
			animationEnd.removeHandler();

		animationEnd = container.addDomHandler(handler, AnimationEndEvent.getType());
	}

	private native void blurBeforeAnimation() /*-{
		var node = $doc.querySelector(":focus");
		if (node != null) {
			if (typeof (node.blur) == "function") {
				node.blur();
			}
		}
	}-*/;

	/**
	 * 沉底
	 * 
	 * @author superman
	 * @version 2018年8月4日 下午9:07:52
	 */
	public void bottom() {
		panelToPopup.setStyleName("flex-h flex-hc flex-ve");
		show();
	}

	/**
	 * 居中展示
	 * 
	 * @author superman
	 * @version 2018年7月24日 下午11:47:16
	 */
	public void center() {
		panelToPopup.setStyleName("flex-h flex-hc flex-vc");
		show();
	}

	/**
	 * 隐藏
	 * 
	 * @author superman
	 * @version 2018年7月24日 下午11:47:12
	 */
	public void hide() {
		if (!isShow)
			return;

		blurBeforeAnimation();
		// 与进入的动画相反就需要添加reverse样式
		container.addStyleName("reserve");
		container.addStyleName("out");

		if (hideAnimationHandler == null) {
			hideAnimationHandler = new AnimationEndHandler() {

				@Override
				public void onAnimationEnd(AnimationEndEvent event) {
					container.removeStyleName("reserve");
					container.removeStyleName("out");
					panelToPopup.removeFromParent();
					isShow = false;
				}
			};
		}
		addAnimationHandler(hideAnimationHandler);
	}

	private void initPopupStyle() {
		panelToPopup.getElement().getStyle().setPosition(Position.FIXED);
		panelToPopup.getElement().getStyle().setProperty("top", "0px");
		panelToPopup.getElement().getStyle().setProperty("bottom", "0px");
		panelToPopup.getElement().getStyle().setProperty("left", "0px");
		panelToPopup.getElement().getStyle().setProperty("right", "0px");
		panelToPopup.getElement().getStyle().setZIndex(100);
		panelToPopup.getElement().getStyle().setBackgroundColor("rgba(0,0,0," + opacity + ")");
	}

	/**
	 * 设置是否点击灰色背景区域可以隐藏
	 * 
	 * @author superman
	 * @version 2018年7月24日 下午11:46:35
	 * @param hideOnBgClick
	 */
	public void setHideOnBackgroundClick(boolean hideOnBgClick) {
		this.hideOnBgClick = hideOnBgClick;
		if (this.hideOnBgClick) {
			panelToPopup.addDomHandler(new ClickHandler() {

				@Override
				public void onClick(ClickEvent event) {
					hide();
				}
			}, ClickEvent.getType());

			if (container != null) {
				container.addDomHandler(new ClickHandler() {

					@Override
					public void onClick(ClickEvent event) {
						event.stopPropagation();
					}
				}, ClickEvent.getType());
			}
		}
	}

	public void setOpacity(double opacity) {
		this.opacity = opacity;
	}

	/**
	 * 显示
	 * 
	 * @author superman
	 * @version 2018年7月24日 下午11:47:08
	 */
	public void show() {
		if (isShow)
			return;
		isShow = true;
		blurBeforeAnimation();
		RootPanel.get().add(panelToPopup);
		initPopupStyle();

		container.addStyleName("in");

		if (showAnimationHandler == null) {
			showAnimationHandler = new AnimationEndHandler() {

				@Override
				public void onAnimationEnd(AnimationEndEvent event) {
					container.removeStyleName("in");
					isShow = true;
				}
			};
		}
		addAnimationHandler(showAnimationHandler);
	}

}
